
/* 
    build command: 
    gcc -Wall host_dump_log.c -o host_dump_log
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>

int is_running = 1;

int create_udp_socket()
{
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    int opt = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
        perror("Setsockopt SO_REUSEADDR failed");
    }

    struct timeval tv;
    tv.tv_sec = 1;
    tv.tv_usec = 0;
    if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
        perror("Setsockopt SO_RCVTIMEO failed");
    }

    return sockfd;
}

void sigint_handler(int sig)
{
    is_running = 0;
}

int main()
{
    int sockfd = create_udp_socket();
    if (sockfd < 0)
        return 0;

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(3768);
    if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0) {
        perror("Invalid address/Address not supported");
        close(sockfd);
        return -1;
    }
    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Connect failed");
        close(sockfd);
        return -1;
    }

    char buffer[2048];
    buffer[0] = 3;
    buffer[1] = 1;
    buffer[2] = 4;
    buffer[3] = 1;
    buffer[4] = 5;
    buffer[5] = 9;
    buffer[6] = 2;
    buffer[7] = 6;
    buffer[8] = 5;
    buffer[9] = 3;
    buffer[10] = 5;
    buffer[11] = 8;

    ssize_t n = send(sockfd, buffer, 12, 0);
    if (n != 12) {
        perror("Send failed");
        return -1;
    }

    signal(SIGINT, sigint_handler);

    struct sockaddr_in remote_addr;
    socklen_t addr_len = sizeof(remote_addr);
    while (is_running) {
        ssize_t recv_len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&remote_addr, &addr_len);
        if (recv_len < 0) {
            if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR) {
                continue;
            }
            perror("Recvfrom failed");
            break;
        }
        buffer[recv_len] = 0;
        printf("%s", buffer);
        fflush(stdout);
    }

    buffer[0] = 2;
    buffer[1] = 9;
    buffer[2] = 9;
    buffer[3] = 7;
    buffer[4] = 9;
    buffer[5] = 2;
    buffer[6] = 4;
    buffer[7] = 5;
    buffer[8] = 8;
    n = send(sockfd, buffer, 9, 0);
    if (n != 9) {
        perror("Send failed");
        return -1;
    }
    shutdown(sockfd, SHUT_RDWR);
    close(sockfd);
    return 0;
}
